﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using PMC.Interfaces;
using PMC.Scripts;
using PMC.Structs;
using System.Net;

namespace PMC
{
    public static class Upgrade
    {
        public static void UpgradeWebsites(string oldfilename, IOverrideable overrideConfirm, INotifyProgress progressNotifier = null)
        {
            if (progressNotifier == null)
                progressNotifier = new ProgressForm();

            progressNotifier.NotifyProgress(0);
            Thread thread = new Thread(() => privateUpgradeWebsites(oldfilename, overrideConfirm, progressNotifier)) { IsBackground = true };
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        private static void privateUpgradeWebsites(string oldfilename, IOverrideable overrideConfirm, INotifyProgress progressNotifier = null)
        {
            bool cancel = false;
            try
            {
                var lines = File.ReadAllLines(oldfilename);
                for (int i = 0; i < lines.Length; i++)
                {
                    var line = lines[i];
                    progressNotifier.NotifyProgress((i * 100 / lines.Length));
                    if (overrideConfirm.Result == DialogResult.Abort)
                    {
                        cancel = true;
                        break;
                    }

                    string[] information = line.Split('|');

                    if (information.Length > 3)
                    {
                        var page = FindWebsite(information[1].ToLower());
                        if (page == null)
                        {
                            continue;
                        }
                        //new Website() {Name = information[0], Webpage = page, Username = information[2], Password = Global.DecryptPassword(information[3]), Script = Plugins.Plugin<Script>.FindPlugin("").Instance};
                        Website.Add(information[0], page, information[2], Global.DecryptPassword(information[3]), Script.Default); //todo Script is default for now
                    }
                }
                if (!cancel)
                {
                    Website.SaveAll();
                }
                progressNotifier.NotifyProgress(100);
            }
            catch (Exception e)
            {
                Log.Instance.AddException(e);
                throw;
            }
        }

        private static Uri FindWebsite(string search)
        {
            return new Uri("http://www." + search + ".nl");

            // Depreceated API code found here:

            //if (!Global.CheckInternetConnection())
            //    throw new ConnectionException();
            //string apiKey = "44E22B89491531AEE1FDD9885D6A88B7576B531D";
            //string market = "nl-nl"; 
            //string format =
            //    "http://api.bing.net/xml.aspx?AppId={0}&Query=site:{1}.nl%20|%20site:{1}.com%20|%20site:{1}.info%20|%20site:{1}.be&Sources=Web&Version=2.0&Market={2}&Adult=Moderate&Options=EnableHighlighting";
            //XmlDocument doc = new XmlDocument();
            //doc.Load(string.Format(format, apiKey, search, market));
            //var urls = doc.GetElementsByTagName("web:Url");

            //if (urls.Count == 0)
            //    return null;//throw new Exception("Expected web:Url-node not found. Website might not be indexed by Bing, the XML-format of Bing was unexpected or Bing may refused the request.");

            //Uri prepareUrl = null;
            //foreach (XmlNode url in urls)
            //{
            //    string uri = url.InnerText;
            //    if (Uri.TryCreate(uri, UriKind.Absolute, out prepareUrl))
            //        break;
            //}
            //if (prepareUrl == null)
            //    return null;//throw new UriFormatException("No web:Url-nodes were valid uri-formats");

            //return new Uri(prepareUrl.Scheme + Uri.SchemeDelimiter + prepareUrl.Host);
        }

        public static void UpgradeExpressions(string path, IOverrideable overrideConfirm)
        {
            TextReader text = null;
            try
            {
                text = new StreamReader(path);
                var line = text.ReadLine();

                while (line != null)
                {
                    if (overrideConfirm.Result == DialogResult.Abort)
                        break;

                    var type = line[0] == '0' ? ExpressionTypes.Expression : ExpressionTypes.Exception;
                    var str = line.Substring(1);
                    var expression = new Expressions(str, type);
                    try
                    {
                        UrlExpressions.Instance.Add(expression);
                    }
                    catch (DuplicateNameException<Expressions> exception)
                    {
                        Log.Instance.AddMessage(exception);
                        //if (overrideConfirm.AllowOverride(exceptio) == DialogResult.Yes) //todo overrideconfirm?
                        //UrlExpressions.Instance.Remove(exception.Object);
                        //UrlExpressions.Instance.Add(expression);
                    }

                    line = text.ReadLine();
                }
                UrlExpressions.Instance.Save();
            }
            catch (Exception e)
            {
                Log.Instance.AddException(e);
                throw;
            }
            finally
            {
                if (text != null)
                    text.Close();
            }
        }
    }
}
